#include "mpp_display_util.h"
#include <drm_fourcc.h>
#include <stdio.h>


/*一下大部分代码都是从rk提供的libdrm中的modetest拿出来用的*/
uint32_t mpp_disp_util::mpp_format_to_bpp(uint32_t format)
{
    uint32_t bpp = 0;
    switch (format) {
        case DRM_FORMAT_NV12:
        case DRM_FORMAT_NV21:
        case DRM_FORMAT_NV16:
        case DRM_FORMAT_NV61:
        case DRM_FORMAT_YUV420:
        case DRM_FORMAT_YVU420:
            bpp = 32;
            break;

        case DRM_FORMAT_ARGB4444:
        case DRM_FORMAT_XRGB4444:
        case DRM_FORMAT_ABGR4444:
        case DRM_FORMAT_XBGR4444:
        case DRM_FORMAT_RGBA4444:
        case DRM_FORMAT_RGBX4444:
        case DRM_FORMAT_BGRA4444:
        case DRM_FORMAT_BGRX4444:
        case DRM_FORMAT_ARGB1555:
        case DRM_FORMAT_XRGB1555:
        case DRM_FORMAT_ABGR1555:
        case DRM_FORMAT_XBGR1555:
        case DRM_FORMAT_RGBA5551:
        case DRM_FORMAT_RGBX5551:
        case DRM_FORMAT_BGRA5551:
        case DRM_FORMAT_BGRX5551:
        case DRM_FORMAT_RGB565:
        case DRM_FORMAT_BGR565:
        case DRM_FORMAT_UYVY:
        case DRM_FORMAT_VYUY:
        case DRM_FORMAT_YUYV:
        case DRM_FORMAT_YVYU:
            bpp = 16;
            break;

        case DRM_FORMAT_BGR888:
        case DRM_FORMAT_RGB888:
            bpp = 24;
            break;

        case DRM_FORMAT_ARGB8888:
        case DRM_FORMAT_XRGB8888:
        case DRM_FORMAT_ABGR8888:
        case DRM_FORMAT_XBGR8888:
        case DRM_FORMAT_RGBA8888:
        case DRM_FORMAT_RGBX8888:
        case DRM_FORMAT_BGRA8888:
        case DRM_FORMAT_BGRX8888:
        case DRM_FORMAT_ARGB2101010:
        case DRM_FORMAT_XRGB2101010:
        case DRM_FORMAT_ABGR2101010:
        case DRM_FORMAT_XBGR2101010:
        case DRM_FORMAT_RGBA1010102:
        case DRM_FORMAT_RGBX1010102:
        case DRM_FORMAT_BGRA1010102:
        case DRM_FORMAT_BGRX1010102:
            bpp = 32;
            break;

        default:
            printf( "unsupported format 0x%08x\n",  format);
            return 0;
        }
        return bpp;
}
uint32_t mpp_disp_util::mpp_format_to_virtual_height(uint32_t format,uint32_t width,uint32_t height)
{
    unsigned int virtual_height = 0;
    switch (format) {
	case DRM_FORMAT_NV12:
	case DRM_FORMAT_NV21:
	case DRM_FORMAT_YUV420:
	case DRM_FORMAT_YVU420:
		virtual_height = height * 3 / 2;
		break;

	case DRM_FORMAT_NV16:
	case DRM_FORMAT_NV61:
		virtual_height = height * 2;
		break;

	default:
		virtual_height = height;
		break;
	}
    return virtual_height;
}
void  mpp_disp_util::mpp_format_depict_sharp(const uint32_t format,
                                                        const uint32_t width, const uint32_t height,
                                                        const uint32_t handle,const uint32_t pitch,
                                                        depict_shape *depict)
{
    switch (format) {
	case DRM_FORMAT_UYVY:
	case DRM_FORMAT_VYUY:
	case DRM_FORMAT_YUYV:
	case DRM_FORMAT_YVYU:
		depict->offsets[0] = 0;
		depict->handles[0] = handle;
		depict->pitches[0] = pitch;

		//planes[0] = virtual;
		break;

	case DRM_FORMAT_NV12:
	case DRM_FORMAT_NV21:
	case DRM_FORMAT_NV16:
	case DRM_FORMAT_NV61:
		depict->offsets[0] = 0;
		depict->handles[0] = handle;
		depict->pitches[0] = pitch;
		depict->pitches[1] = depict->pitches[0];     //--这边的两个参数赋值有点问题 
                                                            //应该是 depict->pitches[1] = depict->pitches[0]/2;才对 有可能是为了对齐
                                                            
		depict->offsets[1] = depict->pitches[0] * height;    
		depict->handles[1] = handle;

		//planes[0] = virtual;
		//planes[1] = virtual + offsets[1];
		break;

	case DRM_FORMAT_YUV420:
	case DRM_FORMAT_YVU420:
		depict->offsets[0] = 0;
		depict->handles[0] = handle;
		depict->pitches[0] = pitch;
		depict->pitches[1] = depict->pitches[0] / 2;        //这里又对，估计是为了对齐
		depict->offsets[1] = depict->pitches[0] * height;
		depict->handles[1] = handle;
		depict->pitches[2] = depict->pitches[1];
		depict->offsets[2] = depict->offsets[1] + depict->pitches[1] * height / 2;
		depict->handles[2] = handle;

		//planes[0] = virtual;
		//planes[1] = virtual + offsets[1];
		//planes[2] = virtual + offsets[2];
		break;

	case DRM_FORMAT_ARGB4444:
	case DRM_FORMAT_XRGB4444:
	case DRM_FORMAT_ABGR4444:
	case DRM_FORMAT_XBGR4444:
	case DRM_FORMAT_RGBA4444:
	case DRM_FORMAT_RGBX4444:
	case DRM_FORMAT_BGRA4444:
	case DRM_FORMAT_BGRX4444:
	case DRM_FORMAT_ARGB1555:
	case DRM_FORMAT_XRGB1555:
	case DRM_FORMAT_ABGR1555:
	case DRM_FORMAT_XBGR1555:
	case DRM_FORMAT_RGBA5551:
	case DRM_FORMAT_RGBX5551:
	case DRM_FORMAT_BGRA5551:
	case DRM_FORMAT_BGRX5551:
	case DRM_FORMAT_RGB565:
	case DRM_FORMAT_BGR565:
	case DRM_FORMAT_BGR888:
	case DRM_FORMAT_RGB888:
	case DRM_FORMAT_ARGB8888:
	case DRM_FORMAT_XRGB8888:
	case DRM_FORMAT_ABGR8888:
	case DRM_FORMAT_XBGR8888:
	case DRM_FORMAT_RGBA8888:
	case DRM_FORMAT_RGBX8888:
	case DRM_FORMAT_BGRA8888:
	case DRM_FORMAT_BGRX8888:
	case DRM_FORMAT_ARGB2101010:
	case DRM_FORMAT_XRGB2101010:
	case DRM_FORMAT_ABGR2101010:
	case DRM_FORMAT_XBGR2101010:
	case DRM_FORMAT_RGBA1010102:
	case DRM_FORMAT_RGBX1010102:
	case DRM_FORMAT_BGRA1010102:
	case DRM_FORMAT_BGRX1010102:
		depict->offsets[0] = 0;
		depict->handles[0] = handle;
		depict->pitches[0] = pitch;

		//planes[0] = virtual;
		break;
	}
}
uint32_t  mpp_disp_util::mpp_format_get_pitch(uint32_t format,uint32_t width)
{
	uint32_t pitch = 0;
	switch (format) {
	case DRM_FORMAT_UYVY:
	case DRM_FORMAT_VYUY:
	case DRM_FORMAT_YUYV:
	case DRM_FORMAT_YVYU:
		// offsets[0] = 0;
		// handles[0] = bo->handle;
		// pitches[0] = bo->pitch;

		pitch = width;
		break;

	case DRM_FORMAT_NV12:
	case DRM_FORMAT_NV21:
	case DRM_FORMAT_NV16:
	case DRM_FORMAT_NV61:
		// offsets[0] = 0;
		// handles[0] = bo->handle;
		// pitches[0] = bo->pitch;
		// pitches[1] = pitches[0];
		// offsets[1] = pitches[0] * height;
		// handles[1] = bo->handle;

		pitch = width;
		break;

	case DRM_FORMAT_YUV420:
	case DRM_FORMAT_YVU420:
		// offsets[0] = 0;
		// handles[0] = bo->handle;
		// pitches[0] = bo->pitch;
		// pitches[1] = pitches[0] / 2;
		// offsets[1] = pitches[0] * height;
		// handles[1] = bo->handle;
		// pitches[2] = pitches[1];
		// offsets[2] = offsets[1] + pitches[1] * height / 2;
		// handles[2] = bo->handle;

		// depict_mem->planes[0] =  (void *) (mmap_addr);
		// depict_mem->planes[1] =  ((void *)(mmap_addr)) + depict->offsets[1];
		// depict_mem->planes[2] =   ((void *)(mmap_addr))  +depict->offsets[2];
		pitch = width;
		break;

	case DRM_FORMAT_ARGB4444:
	case DRM_FORMAT_XRGB4444:
	case DRM_FORMAT_ABGR4444:
	case DRM_FORMAT_XBGR4444:
	case DRM_FORMAT_RGBA4444:
	case DRM_FORMAT_RGBX4444:
	case DRM_FORMAT_BGRA4444:
	case DRM_FORMAT_BGRX4444:
	case DRM_FORMAT_ARGB1555:
	case DRM_FORMAT_XRGB1555:
	case DRM_FORMAT_ABGR1555:
	case DRM_FORMAT_XBGR1555:
	case DRM_FORMAT_RGBA5551:
	case DRM_FORMAT_RGBX5551:
	case DRM_FORMAT_BGRA5551:
	case DRM_FORMAT_BGRX5551:
	case DRM_FORMAT_RGB565:
	case DRM_FORMAT_BGR565:
	case DRM_FORMAT_BGR888:
	case DRM_FORMAT_RGB888:
	case DRM_FORMAT_ARGB8888:
	case DRM_FORMAT_XRGB8888:
	case DRM_FORMAT_ABGR8888:
	case DRM_FORMAT_XBGR8888:
	case DRM_FORMAT_RGBA8888:
	case DRM_FORMAT_RGBX8888:
	case DRM_FORMAT_BGRA8888:
	case DRM_FORMAT_BGRX8888:
	case DRM_FORMAT_ARGB2101010:
	case DRM_FORMAT_XRGB2101010:
	case DRM_FORMAT_ABGR2101010:
	case DRM_FORMAT_XBGR2101010:
	case DRM_FORMAT_RGBA1010102:
	case DRM_FORMAT_RGBX1010102:
	case DRM_FORMAT_BGRA1010102:
	case DRM_FORMAT_BGRX1010102:
		// offsets[0] = 0;
		// handles[0] = bo->handle;
		// pitches[0] = bo->pitch;

		// depict_mem->planes[0] = (void *) (mmap_addr);
		pitch = width*4;
		break;
	}
	return pitch;
}
void  mpp_disp_util::mpp_format_depict_sharp(const uint32_t format,
                                                                const depict_shape *depict,
                                                                const void *mmap_addr,
                                                                depict_men * depict_mem)
{
    switch (format) {
	case DRM_FORMAT_UYVY:
	case DRM_FORMAT_VYUY:
	case DRM_FORMAT_YUYV:
	case DRM_FORMAT_YVYU:
		// offsets[0] = 0;
		// handles[0] = bo->handle;
		// pitches[0] = bo->pitch;

		depict_mem->planes[0] = (void *)mmap_addr;
		break;

	case DRM_FORMAT_NV12:
	case DRM_FORMAT_NV21:
	case DRM_FORMAT_NV16:
	case DRM_FORMAT_NV61:
		// offsets[0] = 0;
		// handles[0] = bo->handle;
		// pitches[0] = bo->pitch;
		// pitches[1] = pitches[0];
		// offsets[1] = pitches[0] * height;
		// handles[1] = bo->handle;

		depict_mem->planes[0] = (void *) (mmap_addr);
		depict_mem->planes[1] = ((void *)(mmap_addr)) + depict->offsets[1];
		break;

	case DRM_FORMAT_YUV420:
	case DRM_FORMAT_YVU420:
		// offsets[0] = 0;
		// handles[0] = bo->handle;
		// pitches[0] = bo->pitch;
		// pitches[1] = pitches[0] / 2;
		// offsets[1] = pitches[0] * height;
		// handles[1] = bo->handle;
		// pitches[2] = pitches[1];
		// offsets[2] = offsets[1] + pitches[1] * height / 2;
		// handles[2] = bo->handle;

		depict_mem->planes[0] =  (void *) (mmap_addr);
		depict_mem->planes[1] =  ((void *)(mmap_addr)) + depict->offsets[1];
		depict_mem->planes[2] =   ((void *)(mmap_addr))  +depict->offsets[2];
		break;

	case DRM_FORMAT_ARGB4444:
	case DRM_FORMAT_XRGB4444:
	case DRM_FORMAT_ABGR4444:
	case DRM_FORMAT_XBGR4444:
	case DRM_FORMAT_RGBA4444:
	case DRM_FORMAT_RGBX4444:
	case DRM_FORMAT_BGRA4444:
	case DRM_FORMAT_BGRX4444:
	case DRM_FORMAT_ARGB1555:
	case DRM_FORMAT_XRGB1555:
	case DRM_FORMAT_ABGR1555:
	case DRM_FORMAT_XBGR1555:
	case DRM_FORMAT_RGBA5551:
	case DRM_FORMAT_RGBX5551:
	case DRM_FORMAT_BGRA5551:
	case DRM_FORMAT_BGRX5551:
	case DRM_FORMAT_RGB565:
	case DRM_FORMAT_BGR565:
	case DRM_FORMAT_BGR888:
	case DRM_FORMAT_RGB888:
	case DRM_FORMAT_ARGB8888:
	case DRM_FORMAT_XRGB8888:
	case DRM_FORMAT_ABGR8888:
	case DRM_FORMAT_XBGR8888:
	case DRM_FORMAT_RGBA8888:
	case DRM_FORMAT_RGBX8888:
	case DRM_FORMAT_BGRA8888:
	case DRM_FORMAT_BGRX8888:
	case DRM_FORMAT_ARGB2101010:
	case DRM_FORMAT_XRGB2101010:
	case DRM_FORMAT_ABGR2101010:
	case DRM_FORMAT_XBGR2101010:
	case DRM_FORMAT_RGBA1010102:
	case DRM_FORMAT_RGBX1010102:
	case DRM_FORMAT_BGRA1010102:
	case DRM_FORMAT_BGRX1010102:
		// offsets[0] = 0;
		// handles[0] = bo->handle;
		// pitches[0] = bo->pitch;

		depict_mem->planes[0] = (void *) (mmap_addr);
		break;
	}

}


int   mpp_disp_util::mpp_get_supported_format(drmModePlanePtr plane, uint32_t* format)
{
	uint32_t i;

    for (i = 0; i < plane->count_formats; i++) {
        if (plane->formats[i] == DRM_FORMAT_XRGB8888 || 
                plane->formats[i] == DRM_FORMAT_ARGB8888 || 
                plane->formats[i] == DRM_FORMAT_RGBA8888) {
            *format = plane->formats[i];
            return 0;
        }
    }
    printf("No suitable formats found!\n");
    return -1;
}